package com.lkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.wxpay.plus.WxPayParam;
import com.github.wxpay.plus.WxPayTemplate;
import com.lkd.common.VMSystem;
import com.lkd.config.TopicConfig;
import com.lkd.contract.OrderCheck;
import com.lkd.contract.VendoutContract;
import com.lkd.contract.VendoutData;
import com.lkd.contract.VendoutResultContract;
import com.lkd.dao.OrderDao;
import com.lkd.emq.MqttProducer;
import com.lkd.entity.OrderEntity;
import com.lkd.exception.LogicException;
import com.lkd.feign.UserServiceFeignClient;
import com.lkd.feign.VmServiceFeignClient;
import com.lkd.service.OrderService;
import com.lkd.vo.ChannelVO;
import com.lkd.vo.PartnerVO;
import com.lkd.vo.PayVO;
import com.lkd.vo.VmVO;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {



    @Autowired
    private VmServiceFeignClient vmServiceFeignClient;

    @Autowired
    private UserServiceFeignClient userServiceFeignClient;


    @Autowired
    private WxPayTemplate wxPayTemplate;
    @Autowired
    private MqttProducer producer;

    // 创建订单，返回支付链接
    @Override
    public Map<String, String> weixinPay(PayVO payVO) {
      //1. 参数校验 innerCode、skuId
        //2. 业务校验
        //2-1 售货机是否存在，是否为运营状态
        VmVO vmVO = vmServiceFeignClient.findByInnerCode(payVO.getInnerCode());
        if(vmVO==null){
            throw new LogicException("售货机不存在!");
        }
        if(vmVO.getStatus() != VMSystem.VM_STATUS_RUNNING){
            throw new LogicException("该售货机非运营状态下无法下单");
        }
        // 2-2 货道库存是否有货，商品是否存在
        ChannelVO channelVO = vmServiceFeignClient.hasCapacity(payVO.getInnerCode(), payVO.getSkuId());
        if(channelVO==null){
            throw new LogicException("该商品售完");
        }
        //3.创建订单
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderNo(channelVO.getInnerCode()+System.nanoTime());//订单编号: 售货机编号+纳秒
        orderEntity.setThirdNo(orderEntity.getOrderNo());//第三方平台单号 与 订单号一致
        orderEntity.setInnerCode(channelVO.getInnerCode()); //设备号
        orderEntity.setAddr(vmVO.getNodeAddr());//点位地址
        orderEntity.setSkuId(channelVO.getSkuId());//商品id
        orderEntity.setSkuName(channelVO.getSkuVO().getSkuName());//商品名称
        orderEntity.setClassId(channelVO.getSkuVO().getClassId());//商品类别
        orderEntity.setStatus(VMSystem.ORDER_STATUS_CREATE);//订单状态-创建
        orderEntity.setAmount(channelVO.getSkuVO().getPrice());//支付金额
        orderEntity.setPrice(channelVO.getSkuVO().getPrice());//商品金额
        orderEntity.setPayType("2");//微信支付
        orderEntity.setPayStatus(VMSystem.PAY_STATUS_NOPAY);//支付状态-未支付
        orderEntity.setNodeId(vmVO.getNodeId());
        orderEntity.setNodeName(vmVO.getNodeName());
        orderEntity.setRegionId(vmVO.getRegionId());
        orderEntity.setRegionName(vmVO.getRegionName());
        orderEntity.setBusinessId(vmVO.getBusinessId());
        orderEntity.setBusinessName(vmVO.getBusinessName());
        orderEntity.setOwnerId(vmVO.getOwnerId());
        //合作商分成 商品加尔 下（分成比例/100）
        PartnerVO partner = userServiceFeignClient.getPartner(vmVO.getOwnerId());
        Integer ratio = partner.getRatio();
        int bill = new BigDecimal(orderEntity.getAmount()).multiply(
                new BigDecimal(ratio).divide(new BigDecimal(100), RoundingMode.HALF_UP)).intValue();
        orderEntity.setBill(bill);
        //保存数据库
        this.save(orderEntity);
        //4.调用第三方微信支付
        WxPayParam wxPayParam = new WxPayParam();
        wxPayParam.setBody(orderEntity.getSkuName());//商品名称
        wxPayParam.setOutTradeNo(orderEntity.getOrderNo());//订单号
        wxPayParam.setTotalFee(1);//支付金额 TODO 写死
        wxPayParam.setOpenid(payVO.getOpenId());//小程序用户id
        wxPayParam.setDuration(600L);//10分钟有效链接

        Map<String, String> payMap = wxPayTemplate.requestPay(wxPayParam);

        //TODO 5 预留位置，延迟消息
        OrderCheck orderCheck = new OrderCheck();
        orderCheck.setInnerCode(payVO.getInnerCode());
        orderCheck.setOrderNo(orderCheck.getOrderNo());
        //todo 临时写成1分钟
        try {
            producer.send("$delayed/60/"+TopicConfig.ORDER_CHECK_TOPIC,2,orderCheck);
            log.info("发送延迟消息成功");
        }catch (Exception e){
            log.info("发送延迟消息失败{}"+orderEntity.getOrderNo());
        }

        return payMap;
    }

    @Override
    public void handlerTimeOutOrder(OrderCheck orderCheck) {
      //1. 校验售货机
        VmVO vmVO = vmServiceFeignClient.findByInnerCode(orderCheck.getInnerCode());
        if(vmVO==null){
            throw new LogicException("售货机不存在");
        }
        //2.校验售货机状态(运营)
        //3.校验订单状态
        LambdaQueryWrapper<OrderEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderEntity::getOrderNo,orderCheck.getOrderNo());
        OrderEntity orderEntity = this.getOne(wrapper);
        if(orderEntity.getStatus() != VMSystem.ORDER_STATUS_CREATE){
            throw new LogicException("状态有误!");
        }
        //4.更新
        // update tb_order set status =4 where order_no = ?
        orderEntity.setStatus(VMSystem.ORDER_STATUS_INVALID);
        this.updateById(orderEntity);
    }

    /*
    * 订单状态修改
    * */
    @Override
    public void payNotify(Map<String, String> resultMap) {
        //1. 取出参数
        String orderSn = resultMap.get("order_sn"); //订单号
        String openId = resultMap.get("openId"); //支付人
        //2. 业务校验
        OrderEntity orderEntity = this.lambdaQuery()
                .eq(OrderEntity::getOrderNo, orderSn)
                .one();
        if(orderEntity == null){
            throw new LogicException("订单不存在");
        }
        if(orderEntity.getStatus() != VMSystem.ORDER_STATUS_CREATE){
            throw new LogicException("订单状态异常");
        }
        //3. 修改订单信息
        orderEntity.setOpenId(openId);//知道哪个微信支付的
        orderEntity.setPayStatus(VMSystem.PAY_STATUS_PAYED);//已支付
        orderEntity.setStatus(VMSystem.ORDER_STATUS_PAYED);
        this.updateById(orderEntity);
        //4.发送出货消息
        // 4-1 消息内容
        VendoutContract vendoutContract = new VendoutContract();
        vendoutContract.setInnerCode(orderEntity.getInnerCode());
        VendoutData vendoutData = new VendoutData();
        vendoutData.setSkuId(orderEntity.getSkuId());
        vendoutData.setOrderNo(orderEntity.getOrderNo());
        vendoutContract.setVendoutData(vendoutData);
        //4-2 发送消息
        try {
            producer.send(TopicConfig.VMS_VENDOUT_TOPIC,2,vendoutContract);
            log.info("发送出货消息成功：{}",orderEntity.getOrderNo());
        }catch (Exception e){
            e.printStackTrace();
            log.error("发送出货消息失败: {}",orderEntity.getOrderNo());
        }

    }

    /*
    * 订单微服务处理出货结果
    * */
    @Override
    public Boolean vendoutResult(VendoutResultContract vendoutContract) {
        //1.查询订单
        OrderEntity orderEntity = this.lambdaQuery()
                .eq(OrderEntity::getOrderNo,
                        vendoutContract.getVendoutData().getOrderNo()).one();

        //2.判断出货结果
        if(vendoutContract.isSuccess()){//成功
            orderEntity.setStatus(VMSystem.ORDER_STATUS_VENDOUT_SUCCESS);
        }else {
            orderEntity.setStatus(VMSystem.ORDER_STATUS_VENDOUT_FAIL);
            orderEntity.setPayStatus(VMSystem.PAY_STATUS_REFUNDIED);
            // todo 调用微信进行退款
        }
        return this.updateById(orderEntity);



    }}